package org.ns.summer.classpath.classreader.entity;

import java.util.HashSet;
import java.util.Set;

import org.ns.summer.classpath.classreader.ClassFile;
import org.ns.summer.classpath.classreader.ConstantInfo;
import org.ns.summer.classpath.classreader.basicinfo.attribute.AttributeInfo;
import org.ns.summer.classpath.classreader.constantinfo.ConstantUtf8;

public class ClassInfoUtils {
	private final static String[] ZERO_STRING_ARR = {};

	public static String[] getInterfaces(ClassFile classFile) {
		String[] res = null;
		String[] interfaces = classFile.interfaces;
		if (interfaces != null) {
			res = formatClassName(interfaces);
		}
		return res;
	}

	public static String getSuperClassName(ClassFile classFile) {
		return formatClassName(classFile.superClass);
	}

	public static String getThisClassName(ClassFile classFile) {
		return formatClassName(classFile.className);
	}

	public static String[] getRuntimeAnnotations(ClassFile classFile) {
		AttributeInfo[] attributeInfos = classFile.attributes;
		if (attributeInfos == null || attributeInfos.length == 0) {
			return ZERO_STRING_ARR;
		}
		AttributeInfo annotationInfo = null;
		for (AttributeInfo attributeInfo : attributeInfos) {
			int nameIndex = attributeInfo.nameIndex;
			ConstantInfo constantInfo = classFile.constantPool.cpInfo[nameIndex];
			if (constantInfo instanceof ConstantUtf8) {
				String attrname = ((ConstantUtf8) constantInfo).value;
				if (AttributeType.equals(AttributeType.RuntimeVisibleAnnotations, attrname)) {
					annotationInfo = attributeInfo;
					break;
				}
			}
		}
		if (annotationInfo == null || annotationInfo.info == null || annotationInfo.info.length == 0) {
			return ZERO_STRING_ARR;
		}
		short[] annIndexs = annotationInfo.info;
		String[] annotations = new String[annIndexs.length];
		int annIndex = 0;
		for (int i = 0; i < annIndexs.length; i++) {
			if (annIndexs[i] == 0 || annIndexs[i] >= classFile.constantPool.cpInfo.length) {
				continue;
			}
			ConstantInfo constantInfo = classFile.constantPool.cpInfo[annIndexs[i]];
			String name = "";
			if (constantInfo instanceof ConstantUtf8) {
				String annname = ((ConstantUtf8) constantInfo).value;
				if (annname == null || annname.isEmpty() || annname.equals(classFile.className)
						|| annname.charAt(0) != 'L') {
					continue;
				}
				name = formatClassName(annname);
				name = name.substring(1, name.length() - 1);
			}
			annotations[annIndex] = name;
			annIndex++;
		}
		if (annIndex == 0) {
			return ZERO_STRING_ARR;
		}
		String[] annotationsx = new String[annIndex];
		System.arraycopy(annotations, 0, annotationsx, 0, annIndex);
		return annotationsx;
	}

	public static String formatClassName(String src) {
		if (src == null) {
			return null;
		}
		return src.replace("\\", ".").replace("/", ".");
	}

	public static String[] formatClassName(String src[]) {
		if (src == null || src.length == 0) {
			return ZERO_STRING_ARR;
		}
		String[] res = new String[src.length];
		for (int i = 0; i < res.length; i++) {
			res[i] = formatClassName(src[i]);
		}
		return res;
	}

	public static Set<String> toHashSet(String[] src) {
		Set<String> set = new HashSet<String>();
		for (int i = 0; i < src.length; i++) {
			set.add(src[i]);
		}
		return set;
	}

}
